<?php

/**
 * 图片类
 */
class Image {

    protected static $_instance = null;
    public $src, $image = false, $wdith, $height, $info, $type;

    function __construct() {
        
    }

    /**
     * 单例方法
     * @return Image
     */
    public static function getInstance() {
        if (null === self::$_instance) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }

    /**
     *
     * @param string $src 需要处理的图片地址
     * @return bool 失败为false
     */
    function from($src) {
        if (!file_exists($src))
            return false;
        $this->from = $src;
        $info = getImageSize($src);
        $this->width = $info[0];
        $this->height = $info[1];
        switch ($info[2]) {
            case 1: $this->image = @imageCreateFromGif($src);
                break;
            case 2: $this->image = @imageCreateFromJpeg($src);
                break;
            case 3: $this->image = @imageCreateFromPng($src);
                break;
            default:;
        }
        return $this;
    }

    /**
     * 重置图片大小
     * @param int $max_width 最大宽度，默认为0
     * @param int $max_height 最大高度，默认为0，如果两者都设置且锁定比例则按照最大高度来缩放
     * @param int $src_x X轴，默认为0
     * @param int $src_y Y轴，默认为0
     * @param int $src_width 从源图截取的宽度，默认为0时使用源图宽度
     * @param int $src_height 从源图截取的高度，默认为0时使用源图高度
     * @param int $lock_ratio 是否锁定比例，默认为True，锁定比例
     * @return bool 成功为true，失败为false
     */
    function resize($max_width = 0, $max_height = 0, $src_x = 0, $src_y = 0, $src_width = 0, $src_height = 0, $lock_ratio = true, $bgcolor = "#000000") {
        if ($src_width == 0)
            $src_width = $this->width;
        if ($src_height == 0)
            $src_height = $this->height;
        if ($max_width <= 0 && $max_height <= 0)
            return false;
        if ($lock_ratio) {

            $src_ratio = ($this->width) / ($this->height);
            $dst_ratio = $max_height ? $max_width / $max_height : 0;
            //echo $src_ratio,'--',$dst_ratio,"<br />";
            if ($dst_ratio > $src_ratio || $max_width == 0) {
                $dst_width = $max_height * $src_ratio;
                $dst_height = $max_height;
            } else {
                $dst_width = $max_width;
                //$dst_height = round($max_width / $src_ratio);
                $dst_height = $max_width / $src_ratio;
            }
            //exit($dst_width."--".$dst_height);
        } else {
            $dst_height = $max_height;
            $dst_width = $max_width;
        }

        list($r, $g, $b) = $this->rgb($bgcolor);
        $tmp = imagecreatetruecolor($dst_width, $dst_height);
        imagealphablending($tmp, false);
        imagefill($tmp, 0, 0, imagecolorallocatealpha($tmp, $r, $g, $b, 127));
        imagesavealpha($tmp, true);

        if (imagecopyresampled($tmp, $this->image, 0, 0, $src_x, $src_y, $dst_width, $dst_height, $src_width, $src_height) === true) {
            $this->width = $dst_width;
            $this->height = $dst_height;
            @imagedestroy($this->image);
            $this->image = imagecreatetruecolor($dst_width, $dst_height);
            imagealphablending($this->image, false);
            imagefill($this->image, 0, 0, imagecolorallocatealpha($this->image, $r, $g, $b, 127));
            imagesavealpha($this->image, true);
            imagecopy($this->image, $tmp, 0, 0, 0, 0, $dst_width, $dst_height);
            @imagedestroy($tmp);
        }
        return $this;
    }

    /**
     * 给图片加水印文字
     * @param string $text 水印文字
     * @param string $font 水印字体
     * @param int $size 文字大小，默认为12
     * @param int $angle 文字倾斜角度，默认为0，不倾斜
     * @param int $x 文字X轴位置，默认为0
     * @param int $y 文字y轴位置，默认为0
     * @param mixed $color 文字颜色，默认为array(0,0,0)，即#000，黑色，可选数组或16进制颜色
     * @return bool 成功为true，失败为false
     */
    function text($text, $font, $size = 12, $angle = 0, $x = 0, $y = 0, $color = array(0, 0, 0)/* array(r,g,b) */) {
        $color = is_array($color) ? $color : $this->rgb($color);
        $bbox = imageftbbox($size, $angle, $font, $text);
        @imagefttext($this->image, $size, $angle, (($x >= 0) ? ($x - $bbox[6]) : ($x + $this->width + $bbox[6] - $bbox[4])), (($y >= 0) ? ($y - $bbox[7]) : ($y + $this->height + $bbox[7] - $bbox[5] - 5)), imagecolorallocate($this->image, $color[0], $color[1], $color[2]), $font, $text);
        return $this;
    }

    /**
     * 16进制的颜色值转换为RGB数组
     * @param string $hex_color 16进制的颜色值，可用缩写
     * @return array 成功时返回RGB数组
     */
    function rgb($hex_color) {
        $color = str_replace('#', '', $hex_color);
        if (strlen($color) > 3) {
            $r = substr($color, 0, 2);
            $g = substr($color, 2, 2);
            $b = substr($color, 4, 2);
        } else {
            $r = substr($color, 0, 1) . substr($color, 0, 1);
            $g = substr($color, 1, 1) . substr($color, 1, 1);
            $b = substr($color, 2, 1) . substr($color, 2, 1);
        }
        return array(hexdec($r), hexdec($g), hexdec($b));
    }

    /**
     * 给图片加图片水印
     * @param string $src 水印图片的地址
     * @param int $x 图片x轴位置，为负时从右开始计算，默认为0
     * @param int $y 图片y轴位置，为负时从底开始计算，默认为0
     * @param int $max_width 水印图片最大宽度，默认为0
     * @param int $max_height 水印图片最大高度，默认为0
     * @param int $lock_ratio 是否锁定比例，默认为True，锁定比例
     * @return bool 成功为true，失败为false
     */
    function watermark($src, $x = 0, $y = 0, $max_width = 0, $max_height = 0, $lock_ratio = true) {
        $wm = new Image($src);
        $wm->from($src);
        if (!is_resource($wm->image))
            return $this;
        if ($max_width > 0 || $max_height > 0)
            $wm->resize($max_width, $max_height, $lock_ratio);
        $x = (int) ($x >= 0) ? $x : ($this->width + $x - $wm->width);
        $y = (int) ($y >= 0) ? $y : ($this->height + $y - $wm->height);

        imagecopy($this->image, $wm->image, $x, $y, 0, 0, $wm->width, $wm->height);
        return $this;
    }

    /**
     * 给图片加特效
     * @param string $effect 特效名称,BLUS(模糊),EDGE(锐化边缘),SHARPA(锐化局部),SHARPB(锐化全局),EMBOSS(浮雕),LIGHT(照亮，曝光)
     * @return 失败时为false，即不进行任何操作
     */
    function effect($effect) {
        switch (strtoupper($effect)) {
            case "BLUR": $matrix = array(array(1 / 9, 1 / 9, 1 / 9), array(1 / 9, 1 / 9, 1 / 9), array(1 / 9, 1 / 9, 1 / 9));
                break;
            case "EDGE": $matrix = array(array(0, -1, 0), array(-1, 4, -1), array(0, -1, 0));
                break;
            case "SHARPA": $matrix = array(array(0, -1, 0), array(-1, 5, -1), array(0, -1, 0));
                break;
            case "SHARPB": $matrix = array(array(-1, -1, -1), array(-1, 16, -1), array(-1, -1, -1));
                break;
            case "EMBOSS": $matrix = array(array(2, 0, 0), array(0, -1, 0), array(0, 0, -1));
                break;
            case "LIGHT": $matrix = array(array(0, 0, 1), array(0, 1, 0), array(1, 0, 0));
                break;
            default:;
        }
        @imageconvolution($this->image, $matrix, 1, 0);
        return $this;
    }

    /**
     * 输出或生成图片
     * @param string $type 生成图片的格式
     * @param string $dst 生成图片地址，默认为null，即输入header信息，输出图片
     * @param int $quality 生成图片的质量，默认为80
     * @return bool 失败时为false
     */
    function output($type, $dst = null, $quality = 80) {
        $type = strtoupper($type);
        if ($dst != null) {
            switch ($type) {
                case "JPG": case "JPEG": return @imageJpeg($this->image, $dst, $quality);
                case "PNG": return @imagePng($this->image, $dst);
                case "GIF": return @imageGif($this->image, $dst);
                default: return false;
            }
        } else {
            switch ($type) {
                case "JPG": case "JPEG":
                    header('Content-type: image/jpeg');
                    return @imageJpeg($this->image, null, $quality);
                case "PNG":
                    header('Content-Type: image/png');
                    return @imagePng($this->image);
                case "GIF":
                    header('Content-type: image/gif');
                    return @imageGif($this->image);
                default: return false;
            }
        }
    }

}
